<template>
  <q-tabs dense inline-label outside-arrows mobile-arrows align="left" active-color="primary">
    <q-route-tab exact replace v-for="item in historys" :to="item.path" :key="getFmtString(item)"
      :name="getFmtString(item)">
      <template v-slot>
        <!-- <q-icon size="1.1rem" v-if="item.meta.icon" :name="item.meta.icon" /> -->
        <span class="item-label">{{ item.meta.title }}</span>
        <q-icon v-if="item.name !== defaultRouter" class="tab-close q-pl-sm" name="close"
          @click.prevent.stop="removeTab(item)" />
        <q-menu touch-position context-menu>
          <q-list dense bordered separator class="bg-white text-dark">
            <q-tab clickable v-close-popup v-ripple>
              <q-item-section @click="关闭左或右侧或其他(item, 2)">
                关闭其他
              </q-item-section>
            </q-tab>
            <q-tab clickable v-close-popup v-ripple>
              <q-item-section @click="关闭左或右侧或其他(item, 1)">
                关闭右侧
              </q-item-section>
            </q-tab>
            <q-tab clickable v-close-popup v-ripple>
              <q-item-section @click="关闭左或右侧或其他(item)">
                关闭左侧
              </q-item-section>
            </q-tab>
            <q-tab clickable v-close-popup v-ripple>
              <q-item-section @click="closeAll">
                关闭所有
              </q-item-section>
            </q-tab>
          </q-list>
        </q-menu>
      </template>
    </q-route-tab>
  </q-tabs>
</template>

<script setup>
import { emitter } from '@/utils/bus.js'
import { computed, onUnmounted, ref, watch, nextTick } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useUserStore } from '@/stores/use_user_store'
import { fmtTitle } from '@/utils/fmtRouterTitle'

defineOptions({
  name: 'HistoryComponent',
})

const route = useRoute()
const router = useRouter()

const getFmtString = (item) => {
  return item.name + JSON.stringify(item.query) + JSON.stringify(item.params)
}

const historys = ref([])
const activeValue = ref('')
const contextMenuVisible = ref(false)

const userStore = useUserStore()

const left = ref(0)
const top = ref(0)
const isCollapse = ref(false)
const isMobile = ref(false)
const 当前tab = ref('')
const defaultRouter = computed(() => userStore.userInfo.authority.defaultRouter)
const openContextMenu = (e) => {
  if (
    historys.value.length === 1 &&
    route.name === defaultRouter.value
  ) {
    return false
  }
  let id = ''
  if (e.srcElement.nodeName === 'SPAN') {
    id = e.srcElement.offsetParent.id
  } else {
    id = e.srcElement.id
  }
  if (id) {
    contextMenuVisible.value = true

    left.value = e.clientX
    top.value = e.clientY + 10
    当前tab.value = id.substring(4)
  }
}

const 首页 = {
  name: defaultRouter.value,
  meta: {
    title: '首页',
  },
  path: "/layout/" + defaultRouter.value,
  query: {},
  params: {},
}

const closeAll = () => {
  historys.value = [首页]
  router.push({ name: defaultRouter.value })
  // contextMenuVisible.value = false
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}

const 关闭左或右侧或其他 = (tab, 哪个 = 0) => {
  const index = historys.value.findIndex((item) => {
    return getFmtString(item) === getFmtString(tab)
  })
  if (哪个 == 0) {
    historys.value.splice(0, index)
  } else if (哪个 == 1) {
    historys.value.splice(index + 1, historys.value.length)
  } else {
    historys.value = [historys.value[index]]
  }
  router.push(tab)
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
}

const isSame = (route1, route2) => {
  if (route1.name !== route2.name) {
    return false
  }
  if (Object.keys(route1.query).length !== Object.keys(route2.query).length || Object.keys(route1.params).length !== Object.keys(route2.params).length) {
    return false
  }
  for (const key in route1.query) {
    if (route1.query[key] !== route2.query[key]) {
      return false
    }
  }
  for (const key in route1.params) {
    if (route1.params[key] !== route2.params[key]) {
      return false
    }
  }
  return true
}

const setTab = (route) => {
  if (!historys.value.some((item) => isSame(item, route))) {
    const obj = {}
    obj.path = route.path
    obj.name = route.name
    obj.meta = { ...route.meta }
    delete obj.meta.matched
    obj.query = route.query
    obj.params = route.params
    historys.value.push(obj)
  }
  window.sessionStorage.setItem('activeValue', getFmtString(route))
  当前tab.value = getFmtString(route)
}

const historyMap = ref({})

const changeTab = (TabsPaneContext) => {
  const name = TabsPaneContext?.props?.name
  if (!name) return
  const tab = historyMap.value[name]
  router.push({
    name: tab.name,
    query: tab.query,
    params: tab.params,
  })
}

const removeTab = (tab) => {
  console.log(`removeTab ing👇`)
  const index = historys.value.findIndex(
    (item) => getFmtString(item) === getFmtString(tab)
  )
  if (getFmtString(route) === getFmtString(tab)) {
    if (historys.value.length === 1) {
      router.push({ name: defaultRouter.value })
    } else {
      let 顶替的tab = historys.value[index - 1]
      if (index < historys.value.length - 1) {
        顶替的tab = historys.value[index + 1]
      }
      console.log(`顶替的tab 👉`, 顶替的tab)
      console.log(`router 👉`, router)
      router.push(顶替的tab)
      console.log(`router 👉`, router)
    }
  }
  historys.value.splice(index, 1)
}

watch(() => contextMenuVisible.value, () => {
  if (contextMenuVisible.value) {
    document.body.addEventListener('click', () => {
      contextMenuVisible.value = false
    })
  } else {
    document.body.removeEventListener('click', () => {
      contextMenuVisible.value = false
    })
  }
})

watch(() => route, (to, now) => {
  if (to.name === 'Login' || to.name === 'Reload') {
    return
  }
  historys.value = historys.value.filter((item) => !item.meta.closeTab)
  setTab(to)
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
  activeValue.value = window.sessionStorage.getItem('activeValue')
}, { deep: true })

watch(() => historys.value, () => {
  sessionStorage.setItem('historys', JSON.stringify(historys.value))
  historyMap.value = {}
  historys.value.forEach((item) => {
    // console.log(`item 👉`, item)
    historyMap.value[getFmtString(item)] = item
  })
  emitter.emit('setKeepAlive', historys.value)
}, {
  deep: true
})

const initPage = () => {
  // 全局监听 关闭当前页面函数
  emitter.on('closeThisPage', () => {
    removeTab(getFmtString(route))
  })
  // 全局监听 关闭所有页面函数
  emitter.on('closeAllPage', () => {
    closeAll()
  })
  emitter.on('mobile', (data) => {
    isMobile.value = data
  })
  emitter.on('collapse', (data) => {
    isCollapse.value = data
  })

  emitter.on('setQuery', (data) => {
    const index = historys.value.findIndex(
      (item) => getFmtString(item) === activeValue.value
    )
    historys.value[index].query = data
    activeValue.value = getFmtString(historys.value[index])
    const currentUrl = window.location.href.split('?')[0]
    const currentSearchParams = new URLSearchParams(data).toString()
    window.history.replaceState({}, '', `${currentUrl}?${currentSearchParams}`)
    sessionStorage.setItem('historys', JSON.stringify(historys.value))
  })

  emitter.on('switchTab', async (data) => {
    const index = historys.value.findIndex((item) => item.name === data.name)
    if (index < 0) {
      return
    }
    for (const key in data.query) {
      data.query[key] = String(data.query[key])
    }
    for (const key in data.params) {
      data.params[key] = String(data.params[key])
    }

    historys.value[index].query = data.query || {}
    historys.value[index].params = data.params || {}
    await nextTick()
    router.push(historys.value[index])
  })
  // console.log(`defaultRouter 👉`, defaultRouter)
  const initHistorys = [首页]
  setTab(route)
  historys.value =
    JSON.parse(sessionStorage.getItem('historys')) || initHistorys
  if (!window.sessionStorage.getItem('activeValue')) {
    activeValue.value = getFmtString(route)
  } else {
    activeValue.value = window.sessionStorage.getItem('activeValue')
  }
  if (window.sessionStorage.getItem('needCloseAll') === 'true') {
    closeAll()
    window.sessionStorage.removeItem('needCloseAll')
  }
}
initPage()

onUnmounted(() => {
  emitter.off('collapse')
  emitter.off('mobile')
})

const middleCloseTab = (e) => {
  if (historys.value.length === 1 && route.name === defaultRouter.value) {
    return false
  }
  let id = ''
  if (e.srcElement.nodeName === 'SPAN') {
    id = e.srcElement.offsetParent.id
  } else {
    id = e.srcElement.id
  }
  if (id) {
    removeTab(id.substring(4))
  }
}
</script>

<style lang="scss" scoped>
.tab-label {
  margin: 0 7px;
  white-space: nowrap;
  max-width: 150px;
  overflow: hidden;
  text-overflow: ellipsis;
}

.tab-close {
  display: inline-flex;
  font-size: 1rem;
  border-radius: 0.2rem;
  opacity: 0.5;
  transition: all 0.3s;

  &:hover {
    opacity: 1;
  }
}
</style>
